package thoven.achievement.net.ideapluginachievement.service

import com.intellij.openapi.components.Service
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.project.Project
import thoven.achievement.net.ideapluginachievement.model.Achievement
import thoven.achievement.net.ideapluginachievement.model.AchievementProgress
import thoven.achievement.net.ideapluginachievement.model.AchievementType
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.temporal.ChronoUnit

/**
 * 智能成就推荐服务
 */
@Service(Service.Level.PROJECT)
class RecommendationService(private val project: Project) {
    
    companion object {
        fun getInstance(project: Project): RecommendationService = project.getService(RecommendationService::class.java)
        private val LOG = logger<RecommendationService>()
    }
    
    private val codeStatsService by lazy { CodeStatsService.getInstance(project) }
    private val settingsService by lazy { SettingsService.getInstance() }
    
    /**
     * 成就推荐建议
     */
    data class AchievementRecommendation(
        val achievement: Achievement,
        val progress: AchievementProgress,
        val recommendation: String,
        val actionSuggestion: String,
        val estimatedTime: String,
        val priority: RecommendationPriority,
        val reason: String
    )
    
    /**
     * 推荐优先级
     */
    enum class RecommendationPriority(val displayName: String, val score: Int) {
        IMMEDIATE("立即可达", 100),
        TODAY("今日可达", 80),
        THIS_WEEK("本周可达", 60),
        LONG_TERM("长期目标", 40),
        CHALLENGING("挑战级", 20)
    }
    
    /**
     * 用户编码习惯分析
     */
    data class CodingPattern(
        val averageDailyLines: Int,
        val peakCodingHour: Int,
        val favoriteLanguages: List<String>,
        val codingStreak: Int,
        val weekendCoding: Boolean,
        val lateNightCoding: Boolean,
        val refactoringHabits: Boolean,
        val consistencyScore: Double // 0-1
    )
    
    /**
     * 获取智能成就推荐（最多返回5个）
     */
    fun getSmartRecommendations(): List<AchievementRecommendation> {
        LOG.info("开始生成智能成就推荐")
        
        val pattern = analyzeCodingPattern()
        val unlockedAchievements = codeStatsService.getUnlockedAchievements()
        val allProgressList = codeStatsService.getAllAchievementProgress()
        
        // 过滤出未解锁的成就
        val availableProgress = allProgressList.filter { progress ->
            !progress.isUnlocked && unlockedAchievements.none { it.type == progress.type }
        }
        
        val recommendations = availableProgress.mapNotNull { progress ->
            generateRecommendation(progress, pattern)
        }.sortedByDescending { it.priority.score }
        
        LOG.info("生成了 ${recommendations.size} 个推荐，用户习惯: ${pattern}")
        
        return recommendations.take(5)
    }
    
    /**
     * 分析用户编码习惯
     */
    private fun analyzeCodingPattern(): CodingPattern {
        val stats = codeStatsService.getTodayStats()
        val aggregated = codeStatsService.getAggregatedStats()
        val state = codeStatsService.getState()
        val consecutiveDays = codeStatsService.getConsecutiveDays()
        
        // 计算平均每日行数（基于最近7天）
        val recentDays = minOf(7, consecutiveDays.coerceAtLeast(1))
        val averageDailyLines = if (recentDays > 0) {
            (aggregated.totalAdded / recentDays.toDouble()).toInt()
        } else {
            aggregated.todayAdded
        }
        
        // 分析编码时间模式
        val codingTimes = state.getCodingStartTimes()
        val peakHour = if (codingTimes.isNotEmpty()) {
            codingTimes.groupBy { it.hour }
                .maxByOrNull { it.value.size }?.key ?: 10
        } else 10
        
        // 分析语言偏好（基于今日数据，简化处理）
        val favoriteLanguages = stats.groupBy { it.language }
            .mapValues { entry -> entry.value.sumOf { stat -> stat.addedLines } }
            .entries.sortedByDescending { it.value }
            .take(3)
            .map { it.key }
        
        // 分析编码习惯
        val lateNightCoding = peakHour >= 22 || peakHour <= 5
        val weekendCoding = state.lastActiveDate?.let {
            val dayOfWeek = it.dayOfWeek
            dayOfWeek.value >= 6 // 周六(6)和周日(7)
        } ?: false
        
        val refactoringHabits = aggregated.totalDeleted > aggregated.totalAdded * 0.3
        
        // 计算一致性分数（基于连续天数和编码规律性）
        val consistencyScore = when {
            consecutiveDays >= 7 -> 1.0
            consecutiveDays >= 3 -> 0.8
            consecutiveDays >= 1 -> 0.6
            else -> 0.3
        }
        
        return CodingPattern(
            averageDailyLines = averageDailyLines,
            peakCodingHour = peakHour,
            favoriteLanguages = favoriteLanguages,
            codingStreak = consecutiveDays,
            weekendCoding = weekendCoding,
            lateNightCoding = lateNightCoding,
            refactoringHabits = refactoringHabits,
            consistencyScore = consistencyScore
        )
    }
    
    /**
     * 为特定成就生成推荐建议
     */
    private fun generateRecommendation(progress: AchievementProgress, pattern: CodingPattern): AchievementRecommendation? {
        val achievement = Achievement(type = progress.type)
        val remainingProgress = progress.targetValue - progress.currentValue
        
        // 根据成就类型生成具体建议
        val (recommendation, actionSuggestion, estimatedTime, priority, reason) = when (progress.type) {
            // 里程碑成就
            AchievementType.WARM_UP, AchievementType.KEYBOARD_FLYING, 
            AchievementType.HARD_WORKER, AchievementType.LEGENDARY_1000,
            AchievementType.CODE_MACHINE -> {
                generateLineCountRecommendation(progress, pattern, remainingProgress)
            }
            
            // 删除相关成就
            AchievementType.DELETE_DB, AchievementType.REFACTOR_MASTER,
            AchievementType.DELETE_AND_RUN -> {
                generateDeletionRecommendation(progress, pattern, remainingProgress)
            }
            
            // 时间相关成就
            AchievementType.EARLY_BIRD -> {
                if (pattern.peakCodingHour <= 7) {
                    Recommendation("你是天然的早起编程者！", "明天早上7点前开始编程", "明天", RecommendationPriority.TODAY, "基于你的编程时间习惯")
                } else {
                    Recommendation("挑战早起编程", "尝试明天早上7点前写代码", "需要调整作息", RecommendationPriority.CHALLENGING, "改变编程时间习惯")
                }
            }
            
            AchievementType.NIGHT_CODER -> {
                if (pattern.lateNightCoding) {
                    Recommendation("夜猫子程序员的专属成就！", "今晚22点后继续编程", "今晚", RecommendationPriority.TODAY, "符合你的夜间编程习惯")
                } else {
                    Recommendation("体验深夜编程", "尝试晚上22点后写代码", "需要调整作息", RecommendationPriority.CHALLENGING, "探索新的编程时间")
                }
            }
            
            AchievementType.MARATHON_CODER -> {
                if (pattern.consistencyScore >= 0.8) {
                    Recommendation("马拉松编程挑战", "连续编程3小时以上", "本周内", RecommendationPriority.THIS_WEEK, "你有很好的编程耐力")
                } else {
                    Recommendation("培养长时间编程习惯", "逐步增加单次编程时长", "长期培养", RecommendationPriority.LONG_TERM, "需要提升编程持久力")
                }
            }
            
            AchievementType.WEEKEND_WARRIOR -> {
                if (pattern.weekendCoding) {
                    Recommendation("周末编程战士！", "这个周末继续编程", "本周末", RecommendationPriority.TODAY, "你有周末编程的习惯")
                } else {
                    Recommendation("尝试周末编程", "利用周末时间写代码", "下个周末", RecommendationPriority.THIS_WEEK, "平衡工作与兴趣编程")
                }
            }
            
            // 连续性成就
            AchievementType.SIGN_IN_DAY1, AchievementType.CRAZY_7_DAYS,
            AchievementType.IRON_30_DAYS, AchievementType.DREAM_100_DAYS -> {
                generateConsistencyRecommendation(progress, pattern, remainingProgress)
            }
            
            // 网络热梗成就
            AchievementType.PARALYZED -> {
                Recommendation("编译错误也是成长", "接受编译错误，继续学习", "编程时", RecommendationPriority.IMMEDIATE, "学习过程的一部分")
            }
            
            AchievementType.YYDS_FOREVER -> {
                if (pattern.averageDailyLines >= 200) {
                    Recommendation("代码量YYDS！", "保持高效编程节奏", "持续", RecommendationPriority.TODAY, "你的编程效率很高")
                } else {
                    Recommendation("提升编程效率", "尝试提高每日代码量", "逐步提升", RecommendationPriority.THIS_WEEK, "培养高效编程习惯")
                }
            }
            
            else -> {
                // 默认推荐
                Recommendation(
                    "继续努力，解锁更多成就",
                    "保持编程习惯",
                    "持续努力",
                    RecommendationPriority.LONG_TERM,
                    "通用建议"
                )
            }
        }
        
        return AchievementRecommendation(
            achievement = achievement,
            progress = progress,
            recommendation = recommendation,
            actionSuggestion = actionSuggestion,
            estimatedTime = estimatedTime,
            priority = priority,
            reason = reason
        )
    }
    
    private data class Recommendation(
        val text: String,
        val action: String,
        val time: String,
        val priority: RecommendationPriority,
        val reason: String
    )
    
    private fun generateLineCountRecommendation(progress: AchievementProgress, pattern: CodingPattern, remaining: Int): Recommendation {
        return when {
            remaining <= pattern.averageDailyLines -> {
                Recommendation(
                    "今天就能解锁！还需要 $remaining 行代码",
                    "继续当前的编程任务",
                    "今天",
                    RecommendationPriority.IMMEDIATE,
                    "基于你的日均编程量"
                )
            }
            remaining <= pattern.averageDailyLines * 3 -> {
                val days = (remaining.toDouble() / pattern.averageDailyLines).toInt() + 1
                Recommendation(
                    "近期可达成！预计还需 $days 天",
                    "保持当前编程节奏",
                    "${days}天内",
                    RecommendationPriority.THIS_WEEK,
                    "符合你的编程习惯"
                )
            }
            remaining <= pattern.averageDailyLines * 7 -> {
                Recommendation(
                    "本周目标，还需 $remaining 行代码",
                    "可以适当增加编程时间",
                    "本周内",
                    RecommendationPriority.THIS_WEEK,
                    "适度挑战"
                )
            }
            else -> {
                Recommendation(
                    "长期目标，还需 $remaining 行代码",
                    "稳步前进，不要急躁",
                    "长期坚持",
                    RecommendationPriority.LONG_TERM,
                    "需要时间积累"
                )
            }
        }
    }
    
    private fun generateDeletionRecommendation(progress: AchievementProgress, pattern: CodingPattern, remaining: Int): Recommendation {
        return if (pattern.refactoringHabits) {
            Recommendation(
                "重构高手！还需删除 $remaining 行",
                "继续代码重构和优化",
                "编程时",
                RecommendationPriority.TODAY,
                "你有良好的重构习惯"
            )
        } else {
            Recommendation(
                "学习代码重构，还需删除 $remaining 行",
                "主动寻找可优化的代码",
                "学习重构技巧",
                RecommendationPriority.THIS_WEEK,
                "培养重构意识"
            )
        }
    }
    
    private fun generateConsistencyRecommendation(progress: AchievementProgress, pattern: CodingPattern, remaining: Int): Recommendation {
        return when {
            pattern.consistencyScore >= 0.8 -> {
                Recommendation(
                    "坚持就是胜利！还需连续 $remaining 天",
                    "保持每日编程习惯",
                    "${remaining}天后",
                    RecommendationPriority.TODAY,
                    "你的一致性很好"
                )
            }
            pattern.consistencyScore >= 0.6 -> {
                Recommendation(
                    "培养连续编程习惯，还需 $remaining 天",
                    "设置每日编程提醒",
                    "需要坚持",
                    RecommendationPriority.THIS_WEEK,
                    "提升一致性"
                )
            }
            else -> {
                Recommendation(
                    "建立编程习惯，目标连续 $remaining 天",
                    "从每天编程30分钟开始",
                    "长期培养",
                    RecommendationPriority.LONG_TERM,
                    "需要建立习惯"
                )
            }
        }
    }
    
    /**
     * 获取今日推荐成就（快速达成的1-2个）
     */
    fun getTodayRecommendations(): List<AchievementRecommendation> {
        return getSmartRecommendations()
            .filter { it.priority == RecommendationPriority.IMMEDIATE || it.priority == RecommendationPriority.TODAY }
            .take(2)
    }
    
    /**
     * 获取本周推荐成就
     */
    fun getWeeklyRecommendations(): List<AchievementRecommendation> {
        return getSmartRecommendations()
            .filter { it.priority == RecommendationPriority.THIS_WEEK }
            .take(3)
    }
}
